package cn.com.common;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import java.util.Vector;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 连接池
 * 
 * @author Administrator
 * 
 */
public class ConnectionPool {
	private static Logger logger = LoggerFactory.getLogger(ConnectionPool.class);
	// 存放连接池对象
	private static Vector<Connection> pool;

	// 连接数据库的url地址
	private String url;

	// 数据库用户
	private String userName;

	// 数据库密码
	private String passWord;

	// 数据库驱动名
	private String driverManager;

	// 连接池大小
	private int poolSize = 50;

	// 连接池的一个对象
	private static ConnectionPool instance;

	private ConnectionPool() 
	{
		init();
	}

	/**
	 * 返回一个连接池对象
	 * 
	 * @return
	 */
	public static ConnectionPool getInstance() 
	{
		if (instance == null) 
		{
			instance = new ConnectionPool();
		}
		return instance;
	}

	/**
	 * 连接池初始化，读取属性文件、连接数据库连接，并添加到集合中保存
	 * 
	 */
	public void init() 
	{
		// poolSize设定保存的连接对象个数
		pool = new Vector<Connection>(poolSize);
		// 读取属性文件
		readConfig();
		// 添加数据库连接对象到集合中
		addConnection();
	}

	/**
	 * 建立连接池的初始连接,并添加连接对象到集合中
	 * 
	 */
	private void addConnection() 
	{
		Connection con;
		for (int i = 0; i < poolSize; ) 
		{
			try 
			{
				Class.forName(driverManager);
				con = DriverManager.getConnection(url, userName, passWord);
				if(con!=null)
				{
					pool.add(con);
					i++;
				}
				
			} catch (ClassNotFoundException e) 
			{
				System.out.println("ClassNotFoundException,please check the db");
			} catch (SQLException e) 
			{
				e.printStackTrace();
				System.out.println("SQLException,please check the db");
			}
		}
	}

	/**
	 * 读取属性文件
	 * 
	 */
	private void readConfig() 
	{
		Properties ps = new Properties();
		FileInputStream fis;
		try 
		{
			fis = new FileInputStream("properties/db.properties");
			ps.load(fis);
			fis.close();
		} catch (FileNotFoundException e) 
		{
			e.printStackTrace();
		} catch (IOException e) 
		{
			e.printStackTrace();
		}
		url = ps.getProperty("url");
		userName = ps.getProperty("userName");
		passWord = ps.getProperty("passWord");
		driverManager = ps.getProperty("driverManager");
		poolSize = Integer.parseInt(ps.getProperty("poolSize"));
		ps.clear();
	}

	/**
	 * 返回一个连接池对象
	 * 
	 * @return
	 */
	public synchronized Connection getConnection() 
	{
		Connection con = null;
		if (pool.size() > 0) 
		{
			try
			{
				con = pool.get(0);
			}catch(Exception e)
			{
				logger.error("从连接池得到链接的时候出错：{}", e.getMessage());
				try 
				{
					con = DriverManager.getConnection(url, userName, passWord);
					return con;
				} 
				catch (SQLException e1) 
				{
					e1.printStackTrace();
					logger.error("从连接池重新建立链接的时候出错：{}", e.getMessage());
				}
			}
			if(pool.contains(con))
			{
				pool.remove(con);
			}
			try 
			{
				if(con.isClosed())
				{
					System.out.println("链接是已经失效的链接");
					con = null;
					con = getConnection();
				}
			} catch (SQLException e) 
			{
				e.printStackTrace();
			}
			
		}else{
			logger.error("连接池里面已经没有链接了：{}");
			System.out.println("connection pool size is not enough");
			try 
			{
				for(int i = 0;i<poolSize;i++)
				{
					con = DriverManager.getConnection(url, userName, passWord);
					pool.add(con);
				}
				con = pool.get(0);
				pool.remove(0);
				try 
				{
					if(con.isClosed())
					{
						System.out.println("链接是已经失效的链接");
						con = null;
						con = getConnection();
					}
				} catch (SQLException e) 
				{
					e.printStackTrace();
				}
				return con;
			} catch (SQLException e) 
			{
				e.printStackTrace();
				logger.error("从连接池重新建立链接的时候出错222：{}", e.getMessage());
			}
		}
		try {
			if(con.isClosed())
			{
				System.out.println("链接是已经失效的链接");
				con = null;
				con = getConnection();
			}
		} catch (SQLException e) 
		{
			e.printStackTrace();
		}
		return con;
	}

	/**
	 * 返回连接池对象
	 * 
	 * @param con
	 */
	public synchronized void returnConnectionPool(Connection con) 
	{
		try 
		{
			if(con == null || con.isClosed()||pool.contains(con))
			{
				return;
			}
		} catch (SQLException e) 
		{
			e.printStackTrace();
			logger.error("归还链接池的时候出了问题：{}", e.getMessage());
		}
		
		if(pool.size()>poolSize)
		{
			try 
			{
				if(!con.isClosed())
				{
					con.close();
				}
				con = null;
			} catch (SQLException e) 
			{
				e.printStackTrace();
				logger.error("关闭链接的时候出了问题：{}", e.getMessage());
			}
		}else
		{
			pool.add(con);
		}
		System.out.println("联结池的数量:"+pool.size());
	}

	/**
	 * 关闭数据库连接并移除
	 * 
	 */
	public void closeConnectionPool() 
	{
		for (int i = 0; i < pool.size(); i++) 
		{
			try 
			{
				pool.get(i).close();
			} catch (SQLException e) 
			{
				e.printStackTrace();
			}
			pool.remove(i);
		}
	}
	/*
	 * 连接池测试成功
	 */
	public static void main(String[] args) 
	{
		ConnectionPool pool=ConnectionPool.getInstance();
		System.out.println(pool.getPool().size());
	}

	public Vector<Connection> getPool() 
	{
		return pool;
	}
}
